/*
 * @Description  : 工具类
 * @Autor        : 杜康
 * @Date         : 2023-03-06 17:18:58 +0800
 * @LastEditors  : 杜康
 * @LastEditTime : 2023-03-24 17:03:59 +0800
 */
import { ElMessage } from "element-plus";
import html2canvas from "html2canvas";
import Cookies from "js-cookie";
import { isEmpty } from "lodash";

/**
 * @description: 提示信息
 * @param {*} code
 * @param {*} msg
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-24 16:59:35 +0800
 */
export const showMsg = (code, msg) => {
  const message = isEmpty(code) ? msg : `API Error Code: ${code}, API Error Massage: ${msg}`;
  ElMessage({
    message,
    type: "error"
  });
};
/**
 * @description: 选中菜单获取父级菜单name/path
 * @param {*} menuList
 * @param {*} toPath
 * @param {*} tempArray
 * @param {*} fat
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-06 17:19:51 +0800
 */
export const checkMenuToBreadCrumb = (menuList, toPath, tempArray, fat) => {
  const tempObj = {};
  for (let i = 0; i < menuList.length; i++) {
    if (toPath === menuList[i].path) {
      if (fat.hasOwnProperty("name")) {
        tempArray.push(fat);
      }
      tempArray.push({
        name: menuList[i].name,
        path: menuList[i].path
      });
      return {
        result: 1,
        breadCrumbList: tempArray
      };
    } else {
      if (menuList[i].children.length !== 0) {
        if (fat?.hasOwnProperty("name")) {
          tempArray.push(fat);
        }
        tempObj.name = menuList[i].name;
        tempObj.path = menuList[i].path;
        const temp = checkMenuToBreadCrumb(menuList[i].children, toPath, tempArray, tempObj);
        if (temp.result === 1) {
          return temp;
        }
      } else {
        continue;
      }
    }
    tempArray = [];
  }
  return {
    result: 0,
    breadCrumbList: tempArray
  };
};

/**
 * @description: 判断字符串是否为JSON对象
 * @param {*} str
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:42:57 +0800
 */
export const isJSON = (str) => {
  if (typeof str == "string") {
    try {
      var obj = JSON.parse(str);
      if (typeof obj == "object" && obj) {
        return true;
      } else {
        return false;
      }
    } catch (e) {
      return false;
    }
  }
};

/**
 * @description: 判断HTML元素是否存在
 * @param {*} elId
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:43:29 +0800
 */
export const hasEle = (elId) => {
  return Boolean(document.getElementById(elId));
};

/**
 * @description: 清空Echarts
 * @param {*} domId
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:43:35 +0800
 */
export const clearEcharts = (domId) => {
  echarts.init(document.getElementById(domId)).clear();
};

/**
 * @description: 生成制定长度数组
 * @param {*} len
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:43:54 +0800
 */
export const generateArray = (len = 10) => {
  return Array.from(new Array(len).keys());
};

/**
 * @description: 利用hasOwnProperty 判断是否存在对象属性 数组去重
 * @param {*} arr
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:44:11 +0800
 */
export const unique = (arr) => {
  let obj = {};
  return arr?.filter((item, index, arr) => {
    return obj?.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true);
  });
};

/**
 * @description: 使用正则表达式格式化 自定义保留decimal位小数，并使用split分隔符的数字格式化
 * @param {*} num 格式化目标数字
 * @param {*} decimal 保留几位小数，默认2位
 * @param {*} split 千分位分隔符，默认为,
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:44:11 +0800
 */
export const moneyFormat = (num, decimal = 2, split = ",") => {
  if (isFinite(num)) {
    // num是数字
    if (num === 0) {
      // 为0
      return num.toFixed(decimal);
    } else {
      // 非0
      let res = "";
      const dotIndex = String(num).indexOf(".");
      if (dotIndex === -1) {
        // 整数
        if (decimal > 0) {
          res = `${String(num).replace(/(\d)(?=(?:\d{3})+$)/g, `$1${split}`)}.${"0".repeat(
            decimal
          )}`;
        } else {
          res = String(num).replace(/(\d)(?=(?:\d{3})+$)/g, `$1${split}`);
        }
      } else {
        // 非整数
        // js四舍五入 Math.round()：正数时4舍5入，负数时5舍6入
        // Math.round(1.5) = 2
        // Math.round(-1.5) = -1
        // Math.round(-1.6) = -2
        // 保留decimals位小数
        const numStr = String(
          (Math.round(num * Math.pow(10, decimal)) / Math.pow(10, decimal)).toFixed(decimal)
        ); // 四舍五入，然后固定保留2位小数
        const decimals = numStr.slice(dotIndex, dotIndex + decimal + 1); // 截取小数位
        res =
          String(numStr.slice(0, dotIndex)).replace(/(\d)(?=(?:\d{3})+$)/g, `$1${split}`) +
          decimals;
      }
      return res;
    }
  } else {
    return "--";
  }
};

/**
 * @description: 删除数组指定元素
 * @param {*} list 需要删除的数组
 * @param {*} delEle 删除目标数据
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:44:11 +0800
 */
export const delArrayEle = (list, delEle) => {
  const INDEX = list?.indexOf(delEle);
  INDEX > 0 ? list?.splice(INDEX, 1) : INDEX;
  return list;
};

/**
 * @description: 校验ArrayBuffer
 * @param {*} data
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-24 16:45:12 +0800
 */
const verifyArrayBuffer = (data) => {
  // 使用TextDecoder
  const enc = new TextDecoder(); //，默认转utf-8
  const response = enc?.decode(new Uint8Array(data));
  if (response?.includes("code")) {
    //文件错误时会返回code码告知错误原因，若成功直接返回文件流
    const { code, data, msg } = JSON.parse(response);
    showMsg(code, msg);
    return false;
  } else {
    return true;
  }
};

/**
 * @description: 下载文件
 * @param {*} data 数据流
 * @param {*} fileName 文件名称
 * @param {*} suffix 文件后缀 默认后缀 xlsx
 * @return {*}
 * @author: 李永兵
 * @Date: 2022-09-19 15:39:53 +0800
 */
export const publicDownLoadFile = (data, fileName, suffix = "xlsx") => {
  if (verifyArrayBuffer(data)) {
    // 获取当前日期及时间
    const DATE = new Date().toLocaleString().replaceAll("/", "-");
    const fileAllName = `${fileName}${DATE}.${suffix}`;
    //  如果支持微软的文件下载方式(ie10+浏览器)
    if (window.navigator.msSaveBlob) {
      try {
        const blobObject = new Blob([data]);
        window.navigator.msSaveBlob(blobObject, fileAllName);
      } catch (e) {
        console.log(e);
      }
    } else {
      //  其他浏览器
      const url = window.URL.createObjectURL(
        new Blob([data], {
          type: "application/json,application/zip,text/csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"
        })
      );
      const link = document.createElement("a");
      link.style.display = "none";
      link.href = url;
      link.setAttribute("download", fileAllName);
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(link.href);
    }
  }
};

/**
 * @description: 去Header获取文件名
 * @param {*} headers
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:56:17 +0800
 */
export const getFileType = (headers) => {
  const contentDisposition = headers?.[`content-disposition`];
  const cds = contentDisposition?.split(";");
  const allFileName = cds?.filter((item) => item.includes(`filename`))?.[0]?.split("=")?.[1];
  const firstIndex = allFileName.indexOf(".");
  const fileName = allFileName?.substring(0, firstIndex);
  const fileType = allFileName?.substring(firstIndex + 1);
  return {
    fileName,
    fileType
  };
};

/**
 * @description: 聚合下载
 * @param {*} data
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:56:46 +0800
 */
export const aggregationDownloadFile = (data) => {
  const { headers } = data;
  const { fileName, fileType } = getFileType(headers);
  downloadFile(data, fileName, fileType);
};

/**
 * @description: 旋转数组
 * @param {*} arr
 * @param {*} k
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:46:14 +0800
 */
export const rotateArray = (arr, k) => {
  const length = arr.length;
  if (!k || length === 0) return arr;
  const step = Math.abs(k % length); // abs 取绝对值

  // O(1)
  const part1 = arr.slice(-step); // O(1)
  const part2 = arr.slice(0, length - step);
  const part3 = part1.concat(part2);
  return part3;
};

/**
 * @description: 图片进行配置
 * @param {*} url
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:50:25 +0800
 */
export const getURLBase64 = (url) => {
  return new Promise((resolve) => {
    let canvas = document.createElement("canvas");
    canvas.height = 900;
    canvas.width = 1550;
    const ctx = canvas.getContext("2d");
    ctx.fillStyle = "#FFF";
    ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    ctx.drawImage(ctx.canvas, 0, 0);
    const img = new Image();
    img.crossOrigin = "Anonymous"; //允许跨域
    img.src = url;
    img.onload = () => {
      ctx.drawImage(img, 50, 50, 1450, 800);
      let dataURL = canvas.toDataURL("image/png", 2);
      canvas = null;
      resolve(dataURL);
    };
  });
};

/**
 * @description: 进行图片下载
 * @param {*} URL
 * @param {*} title
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:50:40 +0800
 */
export const saveImg = async (URL, title) => {
  const DATE = new Date().toLocaleString().replaceAll("/", "-");
  const result = await getURLBase64(URL);
  if (!isEmpty(result)) {
    const LINK = document.createElement("a");
    LINK.href = result;
    LINK.download = `${title}图表${DATE}.png`;
    LINK.click();
  }
};

/**
 * @description: 对ECharts截图保存
 * @param {*} id
 * @param {*} title
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:50:53 +0800
 */
export const downloadChart = (id, title = "") => {
  const element = document.querySelector(`#${id}`);
  const { scrollHeight, scrollWidth, offsetHeight } = element;
  const opts = {
    // 页面过长会导致截屏失败 详见：https://html2canvas.hertzen.com/faq
    scale: 3, // 缩放比例，提高生成图片清晰度
    useCORS: true, // 允许加载跨域的图片
    allowTaint: false, // 允许图片跨域，和 useCORS 二者不可共同使用
    tainttest: true, // 检测每张图片都已经加载完成
    logging: true, // 日志开关，发布的时候记得改成 false
    height: offsetHeight
  };
  html2canvas(element, opts).then((canvas) => {
    saveImg(canvas.toDataURL("png"), title);
  });
};

/**
 * @description: 定时任务
 * @param {*} fun
 * @param {*} delay 默认5秒
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:51:16 +0800
 */
export const timerTask = (fun, delay = 5) => {
  return setInterval(fun, delay * 1000);
};

/**
 * @description: 清除定时任务
 * @param {*} timerId
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:51:37 +0800
 */
export const clearTimer = (timerId) => {
  clearInterval(timerId);
};

/**
 * @description: 睡眠
 * @param {*} fun
 * @param {*} delay 默认5s
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:51:47 +0800
 */
export const sleepTask = (fun, delay = 5) => {
  setTimeout(fun, delay * 1000);
};

/**
 * @description: 首字母大写
 * @param {*} text
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:52:18 +0800
 */
export const firstLetterCap = (text) => {
  return text?.charAt(0)?.toUpperCase() + text?.slice(1);
};

/**
 * @description: 设置Cookie
 * @param {*} name Key
 * @param {*} value 值
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:53:22 +0800
 */
export const setCookie = (name, value = null) => {
  Cookies.set(name, value);
};

/**
 * @description: 读取Cookie
 * @param {*} name Key
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:53:44 +0800
 */
export const getCookie = (name) => {
  const VALUE = Cookies.get(name);
  return isJSON(VALUE) ? JSON?.parse(VALUE) : VALUE;
};

/**
 * @description: 清空Cookie
 * @return {*}
 * @author: 杜康
 * @Date: 2023-03-16 17:54:47 +0800
 */
export const clearAllCookie = () => {
  const KEYS = document.cookie.match(/[^ =;]+(?=\=)/g);
  KEYS?.forEach((item) => {
    if (!isEmpty(item)) {
      setCookie(item);
    }
  });
};
